home *** CD-ROM | disk | FTP | other *** search
/ Speccy ClassiX 1998 / Speccy ClassiX 98.iso / amiga_system / the_aminet / dev / gcc / ixemulsrc.lha / ixemul-41.4 / library / socket.c < prev    next >
C/C++ Source or Header  |  1995-09-27  |  29KB  |  1,301 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  socket.c,v 1.1.1.1 1994/04/04 04:29:41 amiga Exp
  20.  *
  21.  *  socket.c,v
  22.  * Revision 1.1.1.1  1994/04/04  04:29:41  amiga
  23.  * Initial CVS check in.
  24.  *
  25.  * Revision 1.2  1993/11/05  22:02:33  mwild
  26.  * inet.library code, plus NOT YET WORKING code for "own" sockets
  27.  *
  28.  */
  29.  
  30. #define KERNEL
  31. #include "ixemul.h"
  32. #include "kprintf.h"
  33.  
  34. #include <sys/socket.h>
  35. #include <sys/socketvar.h>
  36. #include <sys/ioctl.h>
  37. #include <net/if.h>
  38. #include <net/route.h>
  39. #include <netinet/in.h>
  40. #include "select.h"
  41. #include <machine/param.h>
  42.  
  43. static struct file *getsock (int fdes);
  44. static int soo_read  (struct file *fp, char *buf, int len);
  45. static int soo_write (struct file *fp, char *buf, int len);
  46. static int soo_ioctl (struct file *fp, int cmd, int inout, int arglen, caddr_t data);
  47. static int soo_select(struct file *fp, int select_cmd, int io_mode);
  48. static int soo_close (struct file *fp);
  49.  
  50. /* inet.library is just as weird as ixemul.library... it takes all parameters
  51.    in parameter structures, addressed by d1 (a datareg taking an address..). */
  52. #include "inet.h"
  53.  
  54. int
  55. socket (int domain, int type, int protocol)
  56. {
  57.   struct a {
  58.           short   domain;
  59.           short   type;
  60.           short   protocol;
  61.           char    sigurg;
  62.           char    sigio;
  63.           short   err;
  64.           struct socket *so;
  65.   } uap;
  66.   struct socket *so;
  67.   struct file *fp;
  68.   struct user *p = &u;
  69.   int fd, err, ostat, omask;
  70.  
  71.   if (domain == AF_INET && ! p->u_InetBase)
  72.     {
  73.       errno = ENOSYS;
  74.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  75.       return -1;
  76.     }
  77.  
  78.   ostat = p->p_stat;
  79.   p->p_stat = SWAIT;
  80.   omask = syscall (SYS_sigsetmask, ~0);
  81.   do
  82.     {
  83.       if (err = falloc (&fp, &fd))
  84.         break;
  85.  
  86. #if defined (U_SOCKETS)
  87.       if (domain == AF_INET)
  88.     {
  89. #endif
  90.            uap.domain   = domain;
  91.            uap.type     = type;
  92.            uap.protocol = protocol;
  93.            uap.sigurg   = u.u_sigurg;
  94.            uap.sigio    = u.u_sigio;
  95.            uap.err      = 0;
  96.       
  97.        IN_socket(p->u_InetBase, &uap);
  98.            fp->f_so = uap.so;
  99.            err = uap.err;
  100. #if defined (U_SOCKETS)
  101.     }
  102.       else
  103.     {
  104.        err = socreate (domain, &so, type, protocol);
  105.     }
  106. #endif
  107.       if (err)
  108.     {
  109.       /* free the allocated fd */
  110.       p->u_ofile[fd] = 0;
  111.       fp->f_count = 0;
  112.           break;
  113.     }
  114.     
  115.       fp->f_stb.st_mode = 0666 | S_IFSOCK; /* not always, but.. */
  116.       fp->f_stb.st_size = 128;    /* sizeof mbuf. */
  117.       fp->f_stb.st_blksize = 128;
  118.  
  119.       fp->f_flags  = FREAD|FWRITE;
  120.       fp->f_type   = domain == AF_INET ? DTYPE_SOCKET : DTYPE_USOCKET;
  121.       fp->f_read   = soo_read;
  122.       fp->f_write  = soo_write;
  123.       fp->f_ioctl  = soo_ioctl;
  124.       fp->f_close  = soo_close;
  125.       fp->f_select = soo_select;
  126.     }
  127.   while (0);
  128.   syscall (SYS_sigsetmask, omask);
  129.   if (CURSIG (p))
  130.     SetSignal (0, SIGBREAKF_CTRL_C);
  131.   p->p_stat = ostat;
  132.   if (err == EINTR)
  133.     setrun (FindTask (0));
  134.  
  135.   errno = err;
  136.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  137.   return err ? -1 : fd;
  138. }
  139.  
  140.  
  141. int
  142. bind (int s, caddr_t name, int namelen)
  143. {
  144.   struct a {
  145.           struct socket    *so;
  146.           caddr_t    name;
  147.           short        namelen;
  148.           short        err;
  149.   } uap;
  150.   register struct file *fp = getsock (s);
  151.   struct user *p = &u;
  152.   int ostat, error;
  153.  
  154.   if (! fp)
  155.     return -1;
  156.  
  157.   ostat = p->p_stat;
  158.   p->p_stat = SWAIT;
  159. #if defined (U_SOCKETS)
  160.   if (fp->f_type == DTYPE_SOCKET)
  161.     {
  162. #endif
  163.       uap.so      = fp->f_so;
  164.       uap.name    = name;
  165.       uap.namelen = namelen;
  166.       uap.err     = 0;
  167.   
  168.       IN_bind(p->u_InetBase, &uap);
  169.       error = uap.err;
  170. #if defined (U_SOCKETS)
  171.     }
  172.   else
  173.     {
  174.       struct mbuf *nam;
  175.       error = sockargs (&nam, name, namelen, MT_SONAME);
  176.       if (! error)
  177.     {
  178.           error = sobind (fp->f_so, nam);
  179.           m_freem (nam);
  180.         }
  181.     }
  182. #endif
  183.  
  184.   if (CURSIG (p))
  185.     SetSignal (0, SIGBREAKF_CTRL_C);
  186.   p->p_stat = ostat;
  187.   if (error == EINTR)
  188.     setrun (FindTask (0));
  189.   
  190.   errno = error;
  191.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  192.   return error ? -1 : 0;
  193. }
  194.  
  195. int
  196. listen (int s, int backlog)
  197. {
  198.   struct a {
  199.           struct socket *so;
  200.           short         backlog;
  201.           short         err;
  202.   } uap;
  203.   register struct file *fp = getsock (s);
  204.   struct user *p = &u;
  205.   int ostat, error;
  206.  
  207.   if (! fp)
  208.     return -1;
  209.  
  210.   ostat = p->p_stat;
  211.   p->p_stat = SWAIT;
  212.  
  213. #if defined (U_SOCKETS)
  214.   if (fp->f_type == DTYPE_SOCKET)
  215.     {
  216. #endif
  217.       uap.so      = fp->f_so;
  218.       uap.backlog = backlog;
  219.       uap.err     = 0;
  220.       IN_listen(p->u_InetBase, &uap);
  221.       error = uap.err;
  222. #if defined (U_SOCKETS)
  223.     }
  224.   else
  225.     {
  226.       error = solisten (fp->f_so, backlog);
  227.     }
  228. #endif
  229.   if (CURSIG (p))
  230.     SetSignal (0, SIGBREAKF_CTRL_C);
  231.   p->p_stat = ostat;
  232.   if (error == EINTR)
  233.     setrun (FindTask (0));
  234.  
  235.   errno = error;
  236.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  237.   return error ? -1 : 0;
  238. }
  239.  
  240. int
  241. accept (int s, caddr_t name, int *namelen)
  242. {
  243.   struct a {
  244.           struct socket *so;
  245.           caddr_t name;
  246.           short   namelen;
  247.           short   err;
  248.           struct socket *so2;
  249.   } uap;
  250.   struct file *fp = getsock (s), *fp2;
  251.   struct user *p = &u;
  252.   int err, fd2, ostat;
  253.   
  254.   if (! fp)
  255.     return -1;
  256.     
  257.   ostat = p->p_stat;
  258.   p->p_stat = SWAIT;
  259.   do
  260.     {
  261.       /* first try to get a new descriptor. If that fails, don't even
  262.          bother to call the library */
  263.       if (err = falloc (&fp2, &fd2))
  264.         break;
  265.       
  266. #if defined (U_SOCKETS)
  267.       if (fp->f_type == DTYPE_SOCKET)
  268.         {
  269. #endif
  270.           uap.so      = fp->f_so;
  271.           uap.name    = name;
  272.           uap.namelen = namelen ? *namelen : 0;
  273.           uap.so2      = 0;
  274.           uap.err     = 0;
  275.           IN_accept(p->u_InetBase, &uap);
  276.           if (! uap.so2 && !uap.err)
  277.             uap.err = EINTR;    /* XXX */
  278.       err = uap.err;
  279.           if (namelen)
  280.             *namelen = uap.namelen;
  281.  
  282.           fp2->f_so = uap.so2;
  283. #if defined (U_SOCKETS)
  284.     }
  285.       else
  286.         {
  287.       struct socket *so = fp->f_so;
  288.  
  289.           if ((so->so_options & SO_ACCEPTCONN) == 0) 
  290.             err = EINVAL;
  291.           else if ((so->so_state & SS_NBIO) && so->so_qlen == 0)
  292.         err = EWOULDBLOCK;
  293.       else
  294.         {
  295.           while (so->so_qlen == 0 && so->so_error == 0) 
  296.             {
  297.           if (so->so_state & SS_CANTRCVMORE) 
  298.             {
  299.               so->so_error = ECONNABORTED;
  300.               break;
  301.             }
  302.           if (err = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
  303.               netcon, 0))
  304.             {
  305.               so->so_error = err;
  306.               break;
  307.             }
  308.             }
  309.           if (so->so_error)
  310.             {
  311.               err = so->so_error;
  312.               so->so_error = 0;
  313.         }
  314.           else
  315.             {
  316.               struct socket *aso = so->so_q;
  317.               struct mbuf *nam;
  318.               if (soqremque (aso, 1) == 0)
  319.                 panic ("accept");
  320.               
  321.               fp2->f_so = aso;
  322.               nam = m_get (M_WAIT, MT_SONAME);
  323.               (void) soaccept (aso, nam);
  324.               if (name && namelen)
  325.                 {
  326.                   if (*namelen > nam->m_len)
  327.                     *namelen = nam->m_len;
  328.                   bcopy (mtod (nam, caddr_t), name, *namelen);
  329.                 }
  330.               m_freem (nam);
  331.             }
  332.         }
  333.         }
  334. #endif
  335.  
  336.       if (err)
  337.         {
  338.           /* free the second file */
  339.           u.u_ofile[fd2] = 0;
  340.           fp2->f_count = 0;
  341.           break;
  342.         }
  343.  
  344.     
  345.       fp2->f_stb.st_mode = 0666 | S_IFSOCK; /* not always, but.. */
  346.       fp2->f_stb.st_size = 128;    /* sizeof mbuf.. */
  347.       fp2->f_stb.st_blksize = 128;
  348.  
  349.       fp2->f_flags  = FREAD|FWRITE;
  350.       fp2->f_type   = DTYPE_SOCKET;
  351.       fp2->f_read   = soo_read;
  352.       fp2->f_write  = soo_write;
  353.       fp2->f_ioctl  = soo_ioctl;
  354.       fp2->f_close  = soo_close;
  355.       fp2->f_select = soo_select;
  356.     }
  357.   while (0);
  358.   if (CURSIG (p))
  359.     SetSignal (0, SIGBREAKF_CTRL_C);
  360.   p->p_stat = ostat;
  361.   if (err == EINTR)
  362.     setrun (FindTask (0));
  363.  
  364.   errno = err;
  365.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  366.   return err ? -1 : fd2;
  367. }
  368.  
  369.  
  370. int
  371. connect (int s, caddr_t name, int namelen)
  372. {
  373.   struct a {
  374.           struct socket *so;
  375.           caddr_t name;
  376.           short   namelen;
  377.           short   err;
  378.   } uap;
  379.   register struct file *fp = getsock (s);
  380.   struct user *p = &u;
  381.   int ostat, error;
  382.  
  383.   if (! fp)
  384.     return -1;
  385.  
  386.   ostat = p->p_stat;
  387.   p->p_stat = SWAIT;
  388.  
  389. #if defined (U_SOCKETS)
  390.   if (fp->f_type == DTYPE_SOCKET)
  391.     {
  392. #endif
  393.       uap.so      = fp->f_so;
  394.       uap.name    = name;
  395.       uap.namelen = namelen;
  396.       uap.err     = 0;
  397.       IN_connect(p->u_InetBase, &uap);
  398.       error = uap.err;
  399. #if defined (U_SOCKETS)
  400.     }
  401.   else
  402.     {
  403.       struct socket *so = fp->f_so;
  404.       struct mbuf *nam;
  405.  
  406.       if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))
  407.         {
  408.       error = EALREADY;
  409.       break;
  410.     }
  411.       if (error = sockargs(&nam, name, namelen, MT_SONAME))
  412.     break;
  413.  
  414.       error = soconnect(so, nam);
  415.       if (error)
  416.     goto bad;
  417.       if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) 
  418.     {
  419.       m_freem(nam);
  420.       error = EINPROGRESS;
  421.     }
  422.  
  423.       Forbid ();
  424.       while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)
  425.     if (error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
  426.                    netcon, 0))
  427.       break;
  428.       if (error == 0) 
  429.     {
  430.       error = so->so_error;
  431.       so->so_error = 0;
  432.     }
  433.       Permit ();
  434. bad:
  435.       so->so_state &= ~SS_ISCONNECTING;
  436.       m_freem(nam);
  437.       if (error == ERESTART)
  438.     error = EINTR;
  439.     }
  440. #endif
  441.  
  442.   if (CURSIG (p))
  443.     SetSignal (0, SIGBREAKF_CTRL_C);
  444.   p->p_stat = ostat;
  445.   if (error == EINTR)
  446.     setrun (FindTask (0));
  447.  
  448.   errno = error;
  449.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  450.   return error ? -1 : 0;
  451. }
  452.  
  453. #if 0
  454. /* This function is not available with Commodore sockets. */
  455.  
  456. int
  457. socketpair (int domain, int type, int protocol, int sv[2])
  458. {
  459.   register struct file *fp1, *fp2;
  460.   struct socket *so1, *so2;
  461.   struct user *p = &u;
  462.   int ostat, error;
  463.  
  464.   /* minimal test.. */
  465.   if (!sv[0] || !sv[1])
  466.     {
  467.       errno = EFAULT;
  468.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  469.       return -1;
  470.     }
  471.  
  472.   /* no go with Commo-sockets */
  473.   if (domain == AF_INET)
  474.     {
  475.       errno = EPFNOSUPPORT;
  476.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  477.       return -1;
  478.     }
  479.  
  480.   ostat = p->p_stat;
  481.   p->p_stat = SWAIT;
  482.   do
  483.     {
  484.       /* first try to allocate two descriptors */
  485.       if (error = falloc (&fp1, &sv[0]))
  486.         break;
  487.         
  488.       if (error = falloc (&fp2, &sv[1]))
  489.         {
  490. free_first:
  491.       /* free first descriptor */
  492.           u.u_ofile[sv[0]] = 0;
  493.           fp1->f_count = 0;
  494.           break;
  495.         }
  496.  
  497.       if (error = socreate(domain, &so1, type, protocol))
  498.         {
  499. free_second:
  500.           u.u_ofile[sv[1]] = 0;
  501.           fp2->f_count = 0;
  502.           goto free_first;
  503.         }
  504.  
  505.       if (error = socreate(domain, &so2, type, protocol))
  506.         {
  507. close_so1:
  508.       soclose (so1);
  509.           goto free_second;
  510.         }
  511.       
  512.       if (error = soconnect2(so1, so2))
  513.         {
  514. close_so2:
  515.       soclose (so2);
  516.       goto close_so1;
  517.     }
  518.        
  519.       if (type == SOCK_DGRAM) 
  520.     {
  521.       /*
  522.        * Datagram socket connection is asymmetric.
  523.        */
  524.       if (error = soconnect2(so2, so1))
  525.         goto close_so2;
  526.     }
  527.     }
  528.   while (0);
  529.   p->p_stat = ostat;
  530.  
  531.   if (error == EINTR)
  532.     setrun (FindTask (0));
  533.   
  534.   errno = error;
  535.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  536.   return error ? -1 : 0;
  537. }
  538. #endif
  539.  
  540.  
  541. int
  542. sendto (int s, caddr_t buf, int len, int flags, caddr_t to, int tolen)
  543. {
  544.   struct a {
  545.           struct socket *so;
  546.           caddr_t buf;
  547.           int     len;
  548.           short   flags;
  549.           caddr_t to;
  550.           short   tolen;
  551.           short   err;
  552.           int     rc;
  553.   } uap;
  554.   register struct file *fp = getsock (s);
  555.   struct user *p = &u;
  556.   int ostat;
  557.  
  558.   if (! fp)
  559.     return -1;
  560.  
  561.   ostat = p->p_stat;
  562.   p->p_stat = SWAIT;
  563.   uap.so    = fp->f_so;
  564.   uap.buf   = buf;
  565.   uap.len   = len;
  566.   uap.flags = flags;
  567.   uap.to    = to;
  568.   uap.tolen = tolen;
  569.   uap.err   = 0;
  570.   IN_sendto(p->u_InetBase, &uap);
  571.   if (CURSIG (p))
  572.     SetSignal (0, SIGBREAKF_CTRL_C);
  573.   p->p_stat = ostat;
  574.  
  575.   /* the library doesn't send this to us of course ;-) */
  576.   if (uap.err == EPIPE)
  577.     _psignal (FindTask (0), SIGPIPE);
  578.   if (uap.err == EINTR)
  579.     setrun (FindTask (0));
  580.   
  581.   errno = uap.err;
  582.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  583.   return uap.err ? -1 : uap.rc;
  584. }
  585.  
  586.  
  587. int
  588. send (int s, caddr_t buf, int len, int flags)
  589. {
  590.   struct a {
  591.           struct socket *so;
  592.           caddr_t buf;
  593.           int     len;
  594.           short   flags;
  595.           short   err;
  596.           int     rc;
  597.   } uap;
  598.   register struct file *fp = getsock (s);
  599.   struct user *p = &u;
  600.   int ostat;
  601.  
  602.   if (! fp)
  603.     return -1;
  604.  
  605.   ostat = p->p_stat;
  606.   p->p_stat = SWAIT;
  607.   uap.so    = fp->f_so;
  608.   uap.buf   = buf;
  609.   uap.len   = len;
  610.   uap.flags = flags;
  611.   uap.err   = 0;
  612.   IN_send (p->u_InetBase, &uap);
  613.   if (CURSIG (p))
  614.     SetSignal (0, SIGBREAKF_CTRL_C);
  615.   p->p_stat = ostat;
  616.   
  617.   /* the library doesn't send this to us of course ;-) */
  618.   if (uap.err == EPIPE)
  619.     _psignal (FindTask (0), SIGPIPE);
  620.   if (uap.err == EINTR)
  621.     setrun (FindTask (0));
  622.   
  623.   errno = uap.err;
  624.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  625.   return uap.err ? -1 : uap.rc;
  626. }
  627.  
  628.  
  629. int
  630. sendmsg (int s, caddr_t msg, int flags)
  631. {
  632.   struct a {
  633.           struct socket *so;
  634.           caddr_t msg;
  635.           short   flags;
  636.           short   err;
  637.           int     rc;
  638.   } uap;
  639.   register struct file *fp = getsock (s);
  640.   struct user *p = &u;
  641.   int ostat;
  642.  
  643.   if (! fp)
  644.     return -1;
  645.  
  646.   ostat = p->p_stat;
  647.   p->p_stat = SWAIT;
  648.   uap.so    = fp->f_so;
  649.   uap.msg   = msg;
  650.   uap.flags = flags;
  651.   uap.err   = 0;
  652.   IN_sendmsg (p->u_InetBase, &uap);
  653.   if (CURSIG (p))
  654.     SetSignal (0, SIGBREAKF_CTRL_C);
  655.   p->p_stat = ostat;
  656.   
  657.   /* the library doesn't send this to us of course ;-) */
  658.   if (uap.err == EPIPE)
  659.     _psignal (FindTask (0), SIGPIPE);
  660.   if (uap.err == EINTR)
  661.     setrun (FindTask (0));
  662.   
  663.   errno = uap.err;
  664.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  665.   return uap.err ? -1 : uap.rc;
  666. }
  667.  
  668.  
  669. int
  670. recvfrom (int s, caddr_t buf, int len, int flags, caddr_t from, int *fromlen)
  671. {
  672.   struct a {
  673.           struct socket *so;
  674.           caddr_t buf;
  675.           int     len;
  676.           short   flags;
  677.           caddr_t from;
  678.           short   fromlen;
  679.           short   err;
  680.           int     rc;
  681.   } uap;
  682.   register struct file *fp = getsock (s);
  683.   struct user *p = &u;
  684.   int ostat;
  685.  
  686.   if (! fp)
  687.     return -1;
  688.  
  689.   ostat = p->p_stat;
  690.   p->p_stat = SWAIT;
  691.   uap.so      = fp->f_so;
  692.   uap.buf     = buf;
  693.   uap.len     = len;
  694.   uap.flags   = flags;
  695.   uap.from    = from;
  696.   uap.fromlen = fromlen ? *fromlen : 0;
  697.   uap.err     = 0;
  698.   IN_recvfrom (p->u_InetBase, &uap);
  699.   if (CURSIG (p))
  700.     SetSignal (0, SIGBREAKF_CTRL_C);
  701.   p->p_stat = ostat;
  702.   if (uap.err == EINTR)
  703.     setrun (FindTask (0));
  704.   if (fromlen)
  705.     *fromlen = uap.fromlen;
  706.   
  707.   errno = uap.err;
  708.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  709.   return uap.err ? -1 : uap.rc;
  710. }
  711.  
  712.  
  713. int
  714. recv (int s, caddr_t buf, int len, int flags)
  715. {
  716.   struct a {
  717.           struct socket *so;
  718.           caddr_t buf;
  719.           int     len;
  720.           short   flags;
  721.           short   err;
  722.           int     rc;
  723.   } uap;
  724.   register struct file *fp = getsock (s);
  725.   struct user *p = &u;
  726.   int ostat;
  727.  
  728.   if (! fp)
  729.     return -1;
  730.  
  731.   ostat = p->p_stat;
  732.   p->p_stat = SWAIT;
  733.   uap.so    = fp->f_so;
  734.   uap.buf   = buf;
  735.   uap.len   = len;
  736.   uap.flags = flags;
  737.   uap.err   = 0;
  738.   IN_recv (p->u_InetBase, &uap);
  739.   if (CURSIG (p))
  740.     SetSignal (0, SIGBREAKF_CTRL_C);
  741.   p->p_stat = ostat;
  742.   if (uap.err == EINTR)
  743.     setrun (FindTask (0));
  744.   
  745.   errno = uap.err;
  746.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  747.   return uap.err ? -1 : uap.rc;
  748. }
  749.  
  750.  
  751. int
  752. recvmsg (int s, caddr_t msg, int flags)
  753. {
  754.   struct a {
  755.           struct socket *so;
  756.           caddr_t msg;
  757.           short   flags;
  758.           short   err;
  759.           int     rc;
  760.   } uap;
  761.   register struct file *fp = getsock (s);
  762.   struct user *p = &u;
  763.   int ostat;
  764.  
  765.   if (! fp)
  766.     return -1;
  767.  
  768.   ostat = p->p_stat;
  769.   p->p_stat = SWAIT;
  770.   uap.so    = fp->f_so;
  771.   uap.msg   = msg;
  772.   uap.flags = flags;
  773.   uap.err   = 0;
  774.   IN_recvmsg (p->u_InetBase, &uap);
  775.   if (CURSIG (p))
  776.     SetSignal (0, SIGBREAKF_CTRL_C);
  777.   p->p_stat = ostat;
  778.   if (uap.err == EINTR)
  779.     setrun (FindTask (0));
  780.   
  781.   errno = uap.err;
  782.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  783.   return uap.err ? -1 : uap.rc;
  784. }
  785.  
  786.  
  787. int
  788. shutdown (int s, int how)
  789. {
  790.   struct a {
  791.           struct socket *so;
  792.           short    how;
  793.           short    err;
  794.   } uap;
  795.   register struct file *fp = getsock (s);
  796.   struct user *p = &u;
  797.   int ostat;
  798.  
  799.   if (! fp)
  800.     return -1;
  801.  
  802.   ostat = p->p_stat;
  803.   p->p_stat = SWAIT;
  804.   uap.so  = fp->f_so;
  805.   uap.how = how;
  806.   uap.err = 0;
  807.   IN_shutdown (p->u_InetBase, &uap);
  808.   if (CURSIG (p))
  809.     SetSignal (0, SIGBREAKF_CTRL_C);
  810.   p->p_stat = ostat;
  811.   if (uap.err == EINTR)
  812.     setrun (FindTask (0));
  813.   
  814.   errno = uap.err;
  815.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  816.   return uap.err ? -1 : 0;
  817. }
  818.  
  819.  
  820. int
  821. setsockopt (int s, int level, int name, caddr_t val, int valsize)
  822. {
  823.   struct a {
  824.           struct socket *so;
  825.           short   level;
  826.           short   name;
  827.           caddr_t val;
  828.           short   valsize;
  829.           short   err;
  830.   } uap;
  831.   register struct file *fp = getsock (s);
  832.   struct user *p = &u;
  833.   int ostat;
  834.  
  835.   if (! fp)
  836.     return -1;
  837.  
  838.   ostat = p->p_stat;
  839.   p->p_stat = SWAIT;
  840.   uap.so      = fp->f_so;
  841.   uap.level   = level;
  842.   uap.name    = name;
  843.   uap.val     = val;
  844.   uap.valsize = valsize;
  845.   uap.err     = 0;
  846.   IN_setsockopt (p->u_InetBase, &uap);
  847.   if (CURSIG (p))
  848.     SetSignal (0, SIGBREAKF_CTRL_C);
  849.   p->p_stat = ostat;
  850.   if (uap.err == EINTR)
  851.     setrun (FindTask (0));
  852.  
  853.   errno = uap.err;
  854.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  855.   return uap.err ? -1 : 0;
  856. }
  857.  
  858.  
  859. int
  860. getsockopt (int s, int level, int name, caddr_t val, int *valsize)
  861. {
  862.   struct a {
  863.           struct socket *so;
  864.           short   level;
  865.           short   name;
  866.           caddr_t val;
  867.           short   valsize;
  868.           short   err;
  869.   } uap;
  870.   register struct file *fp = getsock (s);
  871.   struct user *p = &u;
  872.   int ostat;
  873.  
  874.   if (! fp)
  875.     return -1;
  876.  
  877.   ostat = p->p_stat;
  878.   p->p_stat = SWAIT;
  879.   uap.so      = fp->f_so;
  880.   uap.level   = level;
  881.   uap.name    = name;
  882.   uap.val     = val;
  883.   uap.valsize = valsize ? *valsize : 0;
  884.   uap.err     = 0;
  885.   IN_getsockopt (p->u_InetBase, &uap);
  886.   if (CURSIG (p))
  887.     SetSignal (0, SIGBREAKF_CTRL_C);
  888.   p->p_stat = ostat;
  889.   if (uap.err == EINTR)
  890.     setrun (FindTask (0));
  891.   if (valsize)
  892.     *valsize = uap.valsize;
  893.  
  894.   errno = uap.err;
  895.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  896.   return uap.err ? -1 : 0;
  897. }
  898.  
  899.  
  900. #if 0
  901. /* same problem as with socketpair() */
  902. pipe()
  903. {
  904.         register struct file *rf, *wf;
  905.         struct socket *rso, *wso;
  906.         int r;
  907.  
  908.         u.u_error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0);
  909.         if (u.u_error)
  910.                 return;
  911.         u.u_error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0);
  912.         if (u.u_error)
  913.                 goto free;
  914.         rf = falloc();
  915.         if (rf == NULL)
  916.                 goto free2;
  917.         r = u.u_r.r_val1;
  918.         rf->f_flag = FREAD;
  919.         rf->f_type = DTYPE_SOCKET;
  920.         rf->f_ops = &socketops;
  921.         rf->f_data = (caddr_t)rso;
  922.         wf = falloc();
  923.         if (wf == NULL)
  924.                 goto free3;
  925.         wf->f_flag = FWRITE;
  926.         wf->f_type = DTYPE_SOCKET;
  927.         wf->f_ops = &socketops;
  928.         wf->f_data = (caddr_t)wso;
  929.         u.u_r.r_val2 = u.u_r.r_val1;
  930.         u.u_r.r_val1 = r;
  931.         if (u.u_error = unp_connect2(wso, rso))
  932.                 goto free4;
  933.         wso->so_state |= SS_CANTRCVMORE;
  934.         rso->so_state |= SS_CANTSENDMORE;
  935.         return;
  936. free4:
  937.         wf->f_count = 0;
  938.         u.u_ofile[u.u_r.r_val2] = 0;
  939. free3:
  940.         rf->f_count = 0;
  941.         u.u_ofile[r] = 0;
  942. free2:
  943.         (void)soo_close(wso);
  944. free:
  945.         (void)soo_close(rso);
  946. }
  947. #endif
  948.  
  949.  
  950. /*
  951.  * Get socket name.
  952.  */
  953. int
  954. getsockname (int fdes, caddr_t asa, int *alen)
  955. {
  956.   struct a {
  957.           struct socket *so;
  958.           caddr_t asa;
  959.           short   alen;
  960.           short   err;
  961.   } uap;
  962.   register struct file *fp = getsock (fdes);
  963.   struct user *p = &u;
  964.   int ostat;
  965.  
  966.   if (! fp)
  967.     return -1;
  968.  
  969.   ostat = p->p_stat;
  970.   p->p_stat = SWAIT;
  971.   uap.so   = fp->f_so;
  972.   uap.asa  = asa;
  973.   uap.alen = alen ? *alen : 0;
  974.   uap.err  = 0;
  975.   IN_getsockname (p->u_InetBase, &uap);
  976.   if (CURSIG (p))
  977.     SetSignal (0, SIGBREAKF_CTRL_C);
  978.   p->p_stat = ostat;
  979.   if (uap.err == EINTR)
  980.     setrun (FindTask (0));
  981.   if (alen)
  982.     *alen = uap.alen;
  983.  
  984.   errno = uap.err;
  985.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  986.   return uap.err ? -1 : 0;
  987. }
  988.  
  989. /*
  990.  * Get name of peer for connected socket.
  991.  */
  992. int
  993. getpeername (int fdes, caddr_t asa, int *alen)
  994. {
  995.   struct a {
  996.           struct socket *so;
  997.           caddr_t asa;
  998.           short   alen;
  999.           short   err;
  1000.   } uap;
  1001.   register struct file *fp = getsock (fdes);
  1002.   struct user *p = &u;
  1003.   int ostat;
  1004.  
  1005.   if (! fp)
  1006.     return -1;
  1007.  
  1008.   ostat = p->p_stat;
  1009.   p->p_stat = SWAIT;
  1010.   uap.so   = fp->f_so;
  1011.   uap.asa  = asa;
  1012.   uap.alen = alen ? *alen : 0;
  1013.   uap.err  = 0;
  1014.   IN_getpeername (p->u_InetBase, &uap);
  1015.   if (CURSIG (p))
  1016.     SetSignal (0, SIGBREAKF_CTRL_C);
  1017.   p->p_stat = ostat;
  1018.   if (uap.err == EINTR)
  1019.     setrun (FindTask (0));
  1020.   if (alen)
  1021.     *alen = uap.alen;
  1022.  
  1023.   errno = uap.err;
  1024.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1025.   return uap.err ? -1 : 0;
  1026. }
  1027.  
  1028. static struct file *
  1029. getsock (int fdes)
  1030. {
  1031.   register struct file *fp;
  1032.   register struct user *p = &u;
  1033.  
  1034.   if ((unsigned) fdes >= NOFILE)
  1035.     {
  1036.       errno = EBADF;
  1037.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1038.       return 0;
  1039.     }
  1040.  
  1041.   fp = p->u_ofile[fdes];
  1042.   if (fp == NULL)
  1043.     {
  1044.       errno = EBADF;
  1045.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1046.       return (0);
  1047.   }
  1048.   if (fp->f_type != DTYPE_SOCKET && fp->f_type != DTYPE_USOCKET) 
  1049.   {
  1050.       errno = ENOTSOCK;
  1051.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1052.       return (0);
  1053.     }
  1054.   if (fp->f_type == DTYPE_SOCKET && ! p->u_InetBase)
  1055.     {
  1056.       errno = EPIPE; /* ????? */
  1057.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1058.       return 0;
  1059.     }
  1060.   return (fp);
  1061. }
  1062.  
  1063.  
  1064. static int
  1065. soo_read (struct file *fp, char *buf, int len)
  1066. {
  1067.   struct a {
  1068.           struct socket *so;
  1069.           caddr_t buf;
  1070.           int     len;
  1071.           short   flags;
  1072.           short   err;
  1073.           int     rc;
  1074.   } uap;
  1075.   int ostat;
  1076.   struct user *p = &u;
  1077.  
  1078.   ostat = p->p_stat;
  1079.   p->p_stat = SWAIT;
  1080.   uap.so    = fp->f_so;
  1081.   uap.buf   = buf;
  1082.   uap.len   = len;
  1083.   uap.flags = 0;
  1084.   uap.err   = 0;
  1085.   IN_recv (p->u_InetBase, &uap);
  1086.   if (CURSIG (p))
  1087.     SetSignal (0, SIGBREAKF_CTRL_C);
  1088.   p->p_stat = ostat;
  1089.   if (uap.err == EINTR)
  1090.     setrun (FindTask (0));
  1091.   
  1092.   errno = uap.err;
  1093.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1094.   return uap.err ? -1 : uap.rc;
  1095. }
  1096.  
  1097.  
  1098. static int
  1099. soo_write (struct file *fp, char *buf, int len)
  1100. {
  1101.   struct a {
  1102.           struct socket *so;
  1103.           caddr_t buf;
  1104.           int     len;
  1105.           short   flags;
  1106.           short   err;
  1107.           int     rc;
  1108.   } uap;
  1109.   struct user *p = &u;
  1110.   int ostat;
  1111.  
  1112.   ostat = p->p_stat;
  1113.   p->p_stat = SWAIT;
  1114.   uap.so    = fp->f_so;
  1115.   uap.buf   = buf;
  1116.   uap.len   = len;
  1117.   uap.flags = 0;
  1118.   uap.err   = 0;
  1119.   IN_send (p->u_InetBase, &uap);
  1120.   if (CURSIG (p))
  1121.     SetSignal (0, SIGBREAKF_CTRL_C);
  1122.   p->p_stat = ostat;
  1123.   if (uap.err == EINTR)
  1124.     setrun (FindTask (0));
  1125.   
  1126.   errno = uap.err;
  1127.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1128.   return uap.err ? -1 : uap.rc;
  1129. }
  1130.  
  1131.  
  1132.  
  1133. static int
  1134. soo_ioctl (struct file *fp, int cmd, int inout, int arglen, caddr_t data)
  1135. {
  1136.   struct a {
  1137.           struct socket *so;
  1138.           short      cmd;
  1139.           caddr_t data;
  1140.           short   err;
  1141.   } uap;
  1142.   struct user *p = &u;
  1143.   int ostat;
  1144.  
  1145.   /* _SIGH_... they left almost everything neatly as it was in the BSD kernel
  1146.      code they used, but for whatever reason they decided they needed their
  1147.      own kind of ioctl encoding :-((
  1148.      
  1149.      Well then, here we go, and map `normal' cmds into CBM cmds: */
  1150.  
  1151.   switch (cmd)
  1152.    {
  1153.    case    SIOCADDRT    : cmd = ('r'<<8)|1; break;
  1154.    case    SIOCDELRT    : cmd = ('r'<<8)|2; break;
  1155.    case    SIOCSIFADDR    : cmd = ('i'<<8)|3; break;
  1156.    case    SIOCGIFADDR    : cmd = ('i'<<8)|4; break;
  1157.    case    SIOCSIFDSTADDR    : cmd = ('i'<<8)|5; break;
  1158.    case    SIOCGIFDSTADDR    : cmd = ('i'<<8)|6; break;
  1159.    case    SIOCSIFFLAGS    : cmd = ('i'<<8)|7; break;
  1160.    case    SIOCGIFFLAGS    : cmd = ('i'<<8)|8; break;
  1161.    case    SIOCGIFCONF    : cmd = ('i'<<8)|9; break;
  1162.    case    SIOCSIFMTU    : cmd = ('i'<<8)|10; break;
  1163.    case    SIOCGIFMTU    : cmd = ('i'<<8)|11; break;
  1164.    case    SIOCGIFBRDADDR    : cmd = ('i'<<8)|12; break;
  1165.    case    SIOCSIFBRDADDR    : cmd = ('i'<<8)|13; break;
  1166.    case    SIOCGIFNETMASK    : cmd = ('i'<<8)|14; break;
  1167.    case    SIOCSIFNETMASK    : cmd = ('i'<<8)|15; break;
  1168.    case    SIOCGIFMETRIC    : cmd = ('i'<<8)|16; break;
  1169.    case    SIOCSIFMETRIC    : cmd = ('i'<<8)|17; break;
  1170.    case SIOCSARP    : cmd = ('i'<<8)|18; break;
  1171.    case SIOCGARP    : cmd = ('i'<<8)|19; break;
  1172.    case SIOCDARP    : cmd = ('i'<<8)|20; break;
  1173.    case SIOCATMARK    : cmd = ('i'<<8)|21; break;
  1174.    case FIONBIO        : cmd = ('m'<<8)|22; break;
  1175.    case FIONREAD    : cmd = ('m'<<8)|23; break;
  1176.    case FIOASYNC    : cmd = ('m'<<8)|24; break;
  1177.    case SIOCSPGRP    : cmd = ('m'<<8)|25; break;
  1178.    case SIOCGPGRP    : cmd = ('m'<<8)|26; break;
  1179.    
  1180.    default:
  1181.      /* we really don't have to bother the library with cmds we can't even
  1182.         map over... */
  1183.      errno = EINVAL;
  1184.      KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1185.      return -1;
  1186.    }
  1187.  
  1188.   ostat = p->p_stat;
  1189.   p->p_stat = SWAIT;
  1190.   uap.so    = fp->f_so;
  1191.   uap.cmd   = cmd;
  1192.   uap.data  = data;
  1193.   uap.err   = 0;
  1194.   IN_ioctl (p->u_InetBase, &uap);
  1195.   if (CURSIG (p))
  1196.     SetSignal (0, SIGBREAKF_CTRL_C);
  1197.   p->p_stat = ostat;
  1198.   if (uap.err == EINTR)
  1199.     setrun (FindTask (0));
  1200.   
  1201.   errno = uap.err;
  1202.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1203.   return uap.err ? -1 : 0;
  1204. }
  1205.  
  1206.  
  1207. static int
  1208. soo_select (struct file *fp, int select_cmd, int io_mode)
  1209. {
  1210.   struct a {
  1211.           struct socket **sotable;  /* just one socket used */
  1212.       int      *inp;
  1213.       int      *out;
  1214.       int      *exc;
  1215.       void    *process;
  1216.       short      exec_sig;
  1217.       short      numfd;
  1218.       short   err;
  1219.       short   rc;
  1220.   } uap;
  1221.   int ostat;
  1222.   struct user *p = &u;
  1223.   int in, out, exc;
  1224.  
  1225.   switch (io_mode)
  1226.     {
  1227.     case SELMODE_IN:
  1228.       in = 1; out = 0; exc = 0;
  1229.       break;
  1230.     
  1231.     case SELMODE_OUT:
  1232.       in = 0; out = 1; exc = 0;
  1233.       break;
  1234.  
  1235.     case SELMODE_EXC:
  1236.       in = 0; out = 0; exc = 1;
  1237.       break;
  1238.     }
  1239.  
  1240.   ostat = p->p_stat;
  1241.   p->p_stat = SWAIT;
  1242.   uap.sotable = & fp->f_so;
  1243.   uap.inp = ∈
  1244.   uap.out = &out;
  1245.   uap.exc = &exc;
  1246. #if 0
  1247.   uap.process = FindTask (0);
  1248.   uap.exec_sig = p->u_sigio;
  1249. #else
  1250.   /* sigh, above doesn't work.. */
  1251.   uap.process = 0;
  1252.   uap.exec_sig = 0;
  1253. #endif
  1254.   uap.numfd = 1;
  1255.   uap.err = 0;
  1256.   IN_select (p->u_InetBase, &uap);
  1257.   if (CURSIG (p))
  1258.     SetSignal (0, SIGBREAKF_CTRL_C);
  1259.   p->p_stat = ostat;
  1260.       
  1261.   errno = uap.err;
  1262.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1263.   if (select_cmd == SELCMD_PREPARE)
  1264. #if 0
  1265.     return 1 << p->u_sigio;
  1266. #else
  1267.     return 0;
  1268. #endif
  1269.   else
  1270.     return uap.rc == 1 ? 1 : 0;
  1271. }
  1272.  
  1273.  
  1274. static int
  1275. soo_close (struct file *fp)
  1276. {
  1277.   struct a {
  1278.           struct socket *so;
  1279.       short   err;
  1280.   } uap;
  1281.   struct user *p = &u;
  1282.   int err = 0;
  1283.  
  1284.   ix_lock_base ();
  1285.   fp->f_count--;
  1286.   if (fp->f_count == 0)
  1287.     {
  1288.       /* don't have the base locked for IN_close, this MAY block!! */
  1289.       uap.so = fp->f_so;
  1290.       ix_unlock_base ();
  1291.       IN_close (p->u_InetBase, &uap);
  1292.       err = uap.err;
  1293.     }
  1294.   else
  1295.     ix_unlock_base ();
  1296.  
  1297.   errno = err;
  1298.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1299.   return err ? -1 : 0;
  1300. }
  1301.